package cn.iocoder.yudao.module.member.address.service;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.region.RegionUtils;
import cn.iocoder.yudao.framework.region.enums.RegionDataSet;
import cn.iocoder.yudao.module.member.address.dal.dataobject.MemberAddressDO;
import cn.iocoder.yudao.module.member.address.dal.mysql.MemberAddressMapper;
import cn.iocoder.yudao.module.member.address.vo.AppAddressSaveReqVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.api.member.ErrorCodeConstants.ADDRESS_NOT_EXISTS;

/**
 * 用户地址 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class AddressServiceImpl implements AddressService {

    @Resource
    private MemberAddressMapper memberAddressMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createAddress(Long userId, AppAddressSaveReqVO reqVO) {
        // 如果添加的是默认用户地址，则将原默认地址修改为非默认
        if (Boolean.TRUE.equals(reqVO.getDefaultStatus())) {
            List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserId(userId);
            for (MemberAddressDO address : addresses) {
                MemberAddressDO updateObj = new MemberAddressDO();
                updateObj.setId(address.getId());
                updateObj.setDefaultStatus(false);
                memberAddressMapper.updateById(updateObj);
            }
        }
        // 插入
        MemberAddressDO address = BeanUtils.toBean(reqVO, MemberAddressDO.class);
        address.setId(null);
        autoAssignAddress(address, reqVO);
        address.setUserId(userId);
        memberAddressMapper.insert(address);
        // 返回
        return address.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddress(Long userId, AppAddressSaveReqVO reqVO) {
        // 校验存在,校验是否能够操作
        validAddressExists(userId, reqVO.getId());
        // 如果修改的是默认用户地址，则将原默认地址修改为非默认
        if (Boolean.TRUE.equals(reqVO.getDefaultStatus())) {
            List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserId(userId);
            // 排除自己
            for (MemberAddressDO aDo : addresses) {
                if (!Objects.equals(aDo.getId(), reqVO.getId())) {
                    MemberAddressDO updateObj = new MemberAddressDO();
                    updateObj.setId(aDo.getId());
                    updateObj.setDefaultStatus(false);
                    memberAddressMapper.updateById(updateObj);
                }
            }
        }
        // 更新
        MemberAddressDO updateObj = BeanUtils.toBean(reqVO, MemberAddressDO.class);
        autoAssignAddress(updateObj, reqVO);
        memberAddressMapper.updateById(updateObj);
    }

    @Override
    public void deleteAddress(Long userId, Long id) {
        // 校验存在,校验是否能够操作
        validAddressExists(userId, id);
        // 删除
        memberAddressMapper.deleteById(id);
    }

    @Override
    public void clearAddress(Long userId) {
        memberAddressMapper.deleteByUserId(userId);
    }

    private void validAddressExists(Long userId, Long id) {
        MemberAddressDO addressDO = getAddress(userId, id);
        if (addressDO == null) {
            throw exception(ADDRESS_NOT_EXISTS);
        }
    }

    @Override
    public MemberAddressDO getAddress(Long userId, Long id) {
        return memberAddressMapper.selectByIdAndUserId(id, userId);
    }

    @Override
    public List<MemberAddressDO> getAddressList(Long userId) {
        return memberAddressMapper.selectListByUserId(userId);
    }

    @Override
    public MemberAddressDO getDefaultAddress(Long userId) {
        return memberAddressMapper.selectByUserIdAndDefaultStatus(userId);
    }

    @Override
    public void saveDineAddress(Long userId, AppAddressSaveReqVO reqVO) {
        MemberAddressDO addressDO = getDineAddress(userId);
        if (addressDO == null) {
            // 插入
            addressDO = BeanUtils.toBean(reqVO, MemberAddressDO.class);
            addressDO.setId(null);
            autoAssignAddress(addressDO, reqVO);
            addressDO.setUserId(userId);
            addressDO.setDefaultStatus(false);
            addressDO.setIsDine(true);
            memberAddressMapper.insert(addressDO);
            return;
        }
        // 更新
        MemberAddressDO updateObj = BeanUtils.toBean(reqVO, MemberAddressDO.class);
        updateObj.setId(addressDO.getId());
        autoAssignAddress(updateObj, reqVO);
        if (addressDO.getDetailAddress().contains(reqVO.getDetailAddress())) {
            // 当前送餐地址在选择的配送范围内，则保持当前含门牌号的送餐地址不变
            updateObj.setDetailAddress(addressDO.getDetailAddress());
        }
        updateObj.setDefaultStatus(false);
        updateObj.setIsDine(true);
        memberAddressMapper.updateById(updateObj);
    }

    @Override
    public MemberAddressDO getDineAddress(Long userId) {
        return memberAddressMapper.selectByUserIdAndIsDine(userId);
    }

    private void autoAssignAddress(MemberAddressDO addressDO, AppAddressSaveReqVO reqVO) {
        @SuppressWarnings("deprecation") Integer countyId = reqVO.getAreaId();
        if (countyId == null || countyId <= 0) {
            countyId = RegionUtils.convertRegionCodeToId(reqVO.getCountyCode());
        }
        Integer cityId = RegionUtils.getRegionParentId(RegionDataSet.ONLY_LATEST, countyId);
        Integer provinceId = RegionUtils.getRegionParentId(RegionDataSet.ONLY_LATEST, cityId);
        addressDO.setProvinceId(provinceId);
        addressDO.setCityId(cityId);
        addressDO.setAreaId(countyId);
        addressDO.setDetailAddress(reqVO.getDetailAddress());
    }

}
